﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using Models;
using BLL;
using SocketHelper;
using System.Threading;
using System.Diagnostics;
using System.Configuration;
using MySocketHelper;
namespace AGVControlSystemPro
{
    public delegate void ShowInfo(); //创建显示AGV委托
    public delegate void ServerSend(string ip,OrderList objOrderList);//创建一个发送数据的委托
    public delegate void CallInfoImport(List<ExCall> list);//创建一个呼叫信息加载的委托
    public delegate void DeleteCallInfo(int index);//创建一个删除已发送呼叫信息的委托
    public delegate void IPTypeOutput(); //创建一个IP类型委托
    public delegate void TrafficView(List<TrafficInfo> objTraffic);//创建一个显示交管信息的委托
    public delegate void WatchBoard(WatchBoards objWatchBoard);//创建一个看板系统显示委托变量
    public partial class FrmMain : Form
    {
        private AGVInfoManager objAGVInfoManager = new AGVInfoManager();//AGV基本信息访问类
        private AGVCommunicationManager objAGVCommunicationManager = new AGVCommunicationManager();//调度系统协议
        private TrafficManager objTrafficManager = new TrafficManager();//交管访问函数
        private IPTypeManager objIPTypeManager = new IPTypeManager();//IP地址类型访问类
        private RemoteIOManager objRemoteIOManager = new RemoteIOManager(); //远程IO访问类
        private Socket socket = null; //定义一个socket
        SocketManager m_socket = null;
        private ServerHelper objServerHelper = new ServerHelper();//定义一个socket服务端访问类
        private List<string> LoginIPList = new List<string>(); //上线IP列表
        //保存了服务器端所有负责调用通信套接字.Receive方法的线程 
        private List<ExCall> listExCall = new List<ExCall>();//定义一个存储当前所有呼叫的集合
        private List<ExCall> listFinishCall = new List<ExCall>();//定义一个存储呼叫执行完成的集合
        private List<IPType> listIPType = new List<IPType>();//定义一个存储IP类型数据的集合
        private List<TrafficInfo> listTraffic = new List<TrafficInfo>();//创建一个存储当前交管的信息集合
        private List<TrafficInfo> listTrafficOrder = new List<TrafficInfo>();//用来存储所有数据库中交管指令的集合，初始化从数据库获取
        private List<AGVInfo> listLastAGVInfo = new List<AGVInfo>();//创建一个存储当前在线AGV的信息列表
        private Dictionary<string, SocketClientManager> dicSocketClient = new Dictionary<string , SocketClientManager>();//定义一个存储客户端的集合
        private AGVInfo objLastAgvInfo = new AGVInfo(); //当前AGV信息
        private bool isStartTraffic = false;//是否开启交管
        private bool isFinishTrafficControl = false; //是否已完成交管处理，预防数据被覆盖
        private bool isRun = false;//是否启动调度扫描
        private bool exCallLock = false; //呼叫显示上锁标志位，预防呼叫显示和呼叫完成删除时出现故障
        private bool isConnectServer = false;//是否连接服务端的标志位
        Thread objThread = null;//调度系统线程
        public WatchBoard WatchBoarShow;//根据委托创建委托对象
        //public TrafficView TrafficInfoShow;//根据委托创建委托对象
        public event TrafficView TrafficInfoShow;
        Stopwatch sysRunTime = new Stopwatch();
        private string alarmIP = string.Empty; //报警远程IO的IP地址
        private bool alarmSend = false; //报警信息是否已经发送
        private bool alarmClear = false;//报警已清除
        public FrmMain()
        {
            InitializeComponent();
            //用户名显示
            this.lblAdminName.Text = "["+Program.currentAdmins.AdminName+"]";
            this.lblPort.Text = ConfigurationManager.AppSettings["Port"].ToString();//服务器端口号
            alarmIP = ConfigurationManager.AppSettings["AlarmRemoteIOIP"].ToString();//服务器端口号
            //--------------------------获取本地IP--------------------------//
            //ip地址列表
            string hostname = Dns.GetHostName();
            IPHostEntry localhost = Dns.GetHostByName(hostname);
            IPAddress localaddr = localhost.AddressList[0];
            //显示本地IP
            this.lblLocalIP.Text = localaddr.ToString();
            //加载AGV信息
            this.dgvAGV.AutoGenerateColumns = false;
            ShowAGVInfo();
            //获取IP地址信息
            this.listIPType = objIPTypeManager.GetGetAllIPType1();
            //获取所有交管指令数据
            GetAllTrafficOrder();
            
            //启动调度线程
           // ParameterizedThreadStart pts = new ParameterizedThreadStart(TaskScheduling);
            objThread = new Thread(TaskScheduling);
            objThread.IsBackground = true; //该线程为后台线程
            objThread.Start(); //开始线程
            //呼叫显示格式
            this.dgvStandbyCall.AutoGenerateColumns = false;
            new Common.DataGridViewStyle().DgvStyle3(this.dgvStandbyCall);
            new Common.DataGridViewStyle().DgvStyle3(this.dgvFinishCall);
            listExCall = objRemoteIOManager.GetUnfinishCallByTime(DateTime.Now);
           
            //以防数据为空，导致异常
            if (listExCall != null && listExCall.Count != 0) this.dgvStandbyCall.DataSource = listExCall;          
            //统计系统运行时间开始
            sysRunTime.Start();
        }

        #region 委托使用的办法
        /// <summary>
        /// AGV信息加载
        /// </summary>
        private  void ShowAGVInfo()
        {
            this.dgvAGV.DataSource = null;
            new Common.DataGridViewStyle().DgvStyle4(this.dgvAGV);
            listLastAGVInfo = objAGVInfoManager.GetAGVInfo("1"); //获取启动的AGV，并初始化当前状态
            this.dgvAGV.DataSource = listLastAGVInfo; //DataGridView显示AGV状态
        }
        /// <summary>
        /// 构造一个委托一样的办法模型
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="objOrderList"></param>
        private void SendData(string ip, OrderList objOrderList)
        {
            try
            {
                bool result = objAGVCommunicationManager.SendDataByIP(ip, this.objServerHelper.SocketDic,objOrderList);
                if (result == false) MessageBox.Show("发送失败，该AGV可能已掉线","调试提示");
            }
            catch (Exception ex)
            {
                
                MessageBox.Show(ex.Message);
            }
        }
        /// <summary>
        /// 构造一个呼叫信息一样办法模型（委托调用）
        /// </summary>
        /// <param name="list"></param>
        private void LoadCallInfo(List<ExCall> list)
        {
            listExCall.AddRange(list); //数据加载
            this.dgvStandbyCall.AutoGenerateColumns = false;
            this.dgvStandbyCall.DataSource = null;
            this.dgvStandbyCall.DataSource = listExCall;
        }
        private void CallFinish(int index)
        {
            listExCall.RemoveAt(index);
            this.dgvStandbyCall.DataSource = null;
            this.dgvStandbyCall.DataSource = listExCall;
        }
        private void ShowTypeIP()
        {
            this.listIPType = objIPTypeManager.GetGetAllIPType1();
        }
        /// <summary>
        /// 显示行号
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dgvAGV_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
        {
            Common.DataGridViewStyle.DgvRowPostPaint(this.dgvAGV,e);
        }
        /// <summary>
        /// 获取所有AGV交管指令的信息
        /// </summary>
        private void GetAllTrafficOrder()
        {
            this.listTrafficOrder = objTrafficManager.GetAlltrafficInfo();
        }
        #endregion 

        #region 服务端操作函数
        /// <summary>
        /// 启动监听
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnStart_Click(object sender, EventArgs e)
        {

            try
            {
                if (this.btnStart.Text == "启动系统")
                {
                    this.objServerHelper.Port = Convert.ToInt32(this.lblPort.Text.Trim());//服务器端口号
                    this.objServerHelper.IP = IPAddress.Parse(this.lblLocalIP.Text.Trim()); //服务器IP
                    this.objServerHelper.Point = new IPEndPoint(this.objServerHelper.IP, this.objServerHelper.Port);
                    int count = Convert.ToInt32(ConfigurationManager.AppSettings["SocketCount"]); //获取连接个数
                    m_socket = new SocketManager(count, 1024);   //创建一个Socket 监听数20，字节1024
                    m_socket.Init(); //初始化Socket
                    if (m_socket.Start(this.objServerHelper.Point)) //监听成功则启动
                    { 
                        m_socket.ClientNumberChange +=AcceptInfo; //关联监听事件
                        m_socket.ReceiveClientData +=ReceiveMsg; //关联客户端数据接收事件
                        this.btnStart.Text = "停止系统";
                        this.timAGVStaus.Start();//启动状态扫描定时器
                        isRun = true;//启动调度扫描
                        StartTrafficThread();//启动交管
                        this.timAlarm.Start();//报警定时器开始
                    }
                   
                   // StartClientConnectThread(true);
                }
                else
                {
                    ServerClose();//关闭服务器
                    this.btnStart.Text = "启动系统";
                    this.timAGVStaus.Stop();//停止状态扫描定时器
                    this.timAlarm.Stop();//报警定时器失效
                    isRun = false;//停止调度扫描
                    isStartTraffic = false; //停止交管线程
                    isConnectServer = false;//服务端连接线程停止
                    
                    //ServerDisconnect();//断开所有连接的服务端
                   
                }
            }
            catch (Exception ex)
            {               
                MessageBox.Show(ex.Message);
            }
        }
        private void AcceptInfo(int num, AsyncUserToken token)
        {
            try
            {
                if (num == 1)
                {
                    string remoteIP = string.Empty;
                    if (token.Remote != null)
                    {
                        remoteIP = token.Remote.ToString();
                        //将与客户端通信的套接字对象sokConn添加到键值对集合中，并以客户端IP端口作为键
                        this.objServerHelper.SocketDic.Add(remoteIP, token.Socket);
                        //上线IP列表数据加载
                        this.LoginIPList.Add(remoteIP);
                        LoginListShow();
                        //this.lbAGV.Invoke(new Action<List<string>>(s => { this.lbAGV.DataSource = null; this.lbAGV.DataSource = LoginIPList; }), LoginIPList);
                        //AGV在线状态刷新
                        if (token.IPAddress != null)
                            UpdateAGVStatus(true, token.IPAddress.ToString());
                    }
                    
                }
                else if(num == -1)
                {
                    if (this.objServerHelper.SocketDic.Count != 0 && token != null)
                    {
                        
                        //从通信套接字集合中删除被中断连接的通信套接字对象  
                        this.objServerHelper.SocketDic.Remove(token.Remote.ToString()); //删除下线的AGV IP
                        ///从列表中移除被中断的连接 ip:Port 
                        this.LoginIPList.Remove(token.Remote.ToString());
                        LoginListShow();
                        //this.lbAGV.Invoke(new Action<List<string>>(s => { this.lbAGV.DataSource = null; this.lbAGV.DataSource = LoginIPList; }), LoginIPList);
                        //AGV在线状态刷新
                        UpdateAGVStatus(false, token.IPAddress.ToString());
                        //防止远程IO端开再一次上电无效
                        if (token.IPAddress.ToString() == alarmIP)
                        {
                            alarmSend = false;
                            alarmClear = false;
                        }
                        //token.Socket.Close();                   
                    }
                }
            }
            catch (Exception ex)
            {
                
                throw new Exception(ex.Message);
            }
            
        }
        private void ReceiveMsg(AsyncUserToken token, byte[] buffer)
        {
            try
            {
                string ip = token.IPAddress.ToString();//获取IP地址
                int ipType = objIPTypeManager.GetIPTypeByIP(ip, listIPType); //先获取IP地址属于那种类型，根据类型选取解析函数
                /*--------------------------------------------AGV类型的数据接收--------------------------------------------*/
                if (ipType == 1)
                {
                    AGVInfo objPreAGVInfo = listLastAGVInfo.Find(s => s.IP == ip.ToString()); //根据IP寻找到当前AGV其他信息
                    if (objPreAGVInfo != null)
                    {
                        AGVInfo objAgvData = objAGVCommunicationManager.ResolutionProtocol(buffer, objPreAGVInfo); //AGV协议信息的解析
                        if(objAgvData!=null)UpdateAGVStatus(objAgvData);
                        this.toolStripStatusLabel6.Text = token.BufferCount.ToString();                      
                    }
                }
                /*------------------------------------------远程IO类型的数据接收------------------------------------------*/
                else if (ipType == 2)
                {
                   List<ExCall> objExCall = objRemoteIOManager.ResolutionProtocol(buffer, ip.ToString()); //获取远程IO的呼叫信息
                    if (objExCall != null && objExCall.Count !=0) //呼叫的IO没有存在则不显示，只显示存在的IO
                    {                      
                       // exCallLock = true;//显示上锁
                        listExCall.AddRange(objExCall);
                        while (exCallLock) ;//等待处理完再显示
                        objRemoteIOManager.AddStandbyCall(this.dgvStandbyCall, listExCall); //刷新显示
                        //添加一个呼叫信息到数据库 已经搬到数据接收那里处理
                        //objRemoteIOManager.AddUnfinishCall(objExCall);
                       // exCallLock = false; //显示解锁
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            
        }
        /// <summary>
        /// 服务端关闭
        /// </summary>
        private void ServerClose()
        {
            foreach (AsyncUserToken item in this.m_socket.ClientList)
            {
                UpdateAGVStatus(false, item.IPAddress.ToString()); //掉线显示
            }
            //关闭所有客户端的连接
            //if (this.m_socket.ClientList.Count != 0)
            //{
            //    foreach (AsyncUserToken item in this.m_socket.ClientList)
            //    {
            //        this.m_socket.CloseClient(item);
            //    }
            //}
            m_socket.Stop(); //服务端停止工作
            this.objServerHelper.SocketDic.Clear(); //清空上线IP列表
            this.LoginIPList.Clear(); //清空列表
            this.lbAGV.Invoke(new Action<List<string>>(s =>
            {
                this.lbAGV.DataSource = null;
                this.lbAGV.DataSource = LoginIPList; //显示列表清空 
            }), this.LoginIPList);                    
        }
        private void LoginListShow()
        {
            this.lbAGV.Invoke(new Action<List<string>>(s => { this.lbAGV.DataSource = null; this.lbAGV.DataSource = LoginIPList; }), LoginIPList);
        }
        #endregion

        #region 交通管制线程
        private void StartTrafficThread()
        {
            //创建一个交管的现场
            //ParameterizedThreadStart pts = new ParameterizedThreadStart(TrafficThread);
            Thread th = new Thread(TrafficThread);
            th.IsBackground = true; //该线程为后台线程
            th.Start(); //开始线程
            isStartTraffic = true; //启动交管线程

            //Thread th2 = new Thread(ShowTrafficView);
            //th2.IsBackground = true; //该线程为后台线程
            //th2.Start(); //开始线程
        }
        /// <summary>
        /// 交管线程
        /// </summary>
        /// <param name="o">当前AGV详细信息</param>
        private void TrafficThread( )
        {
            while (true)
            {                
                if (isStartTraffic)
                {
                    try
                    {
                        isFinishTrafficControl = true;
                        //objTrafficManager.TrafficControl(listTraffic, this.dgvAGV, this.objServerHelper.SocketDic, this.listTrafficOrder,this.dgvTrafficView); //执行交管
                        foreach (DataGridViewRow dgvr in dgvAGV.Rows)
                        {
                            //封装AGV当前信息
                            AGVInfo objAGV = new AGVInfo()
                            {
                                AGVName = dgvr.Cells["AGVName"].Value!=null?dgvr.Cells["AGVName"].Value.ToString():"",
                                IP = dgvr.Cells["IP"].Value!=null? dgvr.Cells["IP"].Value.ToString():"",
                                PreLandNum = dgvr.Cells["PreLandNum"].Value!=null?Convert.ToInt32(dgvr.Cells["PreLandNum"].Value):0,
                                PreAGVStatus = dgvr.Cells["PreAGVStatus"].Value!=null?dgvr.Cells["PreAGVStatus"].Value.ToString():"",
                                OnLineStatus = dgvr.Cells["OnLineStatus"].Value!=null?dgvr.Cells["OnLineStatus"].Value.ToString():"",
                            };
                            
                            //【1】先判断状态是否合适
                            if (objAGV.PreAGVStatus != "失联" && objAGV.OnLineStatus != "离线")
                            {                                                                
                                //【2】地标判断，不能为0
                                if (objAGV.PreLandNum != 0)
                                {
                                    //【3】查询地标是否存在交管功能
                                    List<TrafficInfo> listTrafficCmd = this.listTrafficOrder.FindAll(s=>s.LandNum==objAGV.PreLandNum);
                                    //List<TrafficInfo> listTrafficCmd =objTrafficManager.GettrafficInfoByLandNum(objAGV.PreLandNum.ToString());
                                    //【4】如果存在交管功能则进入
                                    if (listTrafficCmd.Count != 0)
                                    {
                                        //【5】进入交管管理算法
                                        foreach (TrafficInfo item in listTrafficCmd)
                                        {
                                            /*-----------------------------------------------------------管制指令执行-----------------------------------------------------------*/
                                            if (item.CMD == 0)
                                            {
                                                int landNum = dgvr.Cells["PreLandNum"].Value != null ? Convert.ToInt32(dgvr.Cells["PreLandNum"].Value) : 0;
                                                if (landNum == objAGV.PreLandNum && item.LandNum == landNum)
                                                {
                                                    //寻找该区域的交管是否已经存在，存在则管制该AGV(需要增加一个状态：是否已被管制主，如果都被管制主，则一直通过交管区域。有没有没管制主，则被管制)
                                                    List<TrafficInfo> listInTraffic = listTraffic.FindAll(s => s.Area == item.Area && s.IP != objAGV.IP);
                                                    //判断在该区域是否已经存在该IP的AGV
                                                    TrafficInfo listIsExistsTraffic = listTraffic.Find(s => s.Area == item.Area && s.IP == objAGV.IP);
                                                    //存在交管AGV && 并不是本AGV
                                                    if (listInTraffic.Count != 0 && listIsExistsTraffic == null)
                                                    {
                                                        //发送停止信号
                                                        OrderList objOrderList = new OrderList() { CMD = 0x14 };
                                                        objAGVCommunicationManager.SendDataByIP(objAGV.IP, this.objServerHelper.SocketDic, objOrderList);//发送数据
                                                        listTraffic.Add(new TrafficInfo() { AGVName = objAGV.AGVName, IP = objAGV.IP, Area = item.Area, InTraffic = DateTime.Now, TrafficStatus = "管制中", LandNum = objAGV.PreLandNum });
                                                    }
                                                    else if (listInTraffic.Count == 0 && listIsExistsTraffic == null)
                                                    {
                                                        listTraffic.Add(new TrafficInfo() { AGVName = objAGV.AGVName, IP = objAGV.IP, Area = item.Area, LandNum = objAGV.PreLandNum, InTraffic = DateTime.Now, TrafficStatus = "通行中" });
                                                    }
                                                }
                                                
                                            }
                                            /*-----------------------------------------------------------释放指令执行-----------------------------------------------------------*/
                                            else if (item.CMD == 1)
                                            {
                                                //查找对应区域和交管AGV，并清除该AGV在交管区域的信息（释放交管）
                                                int index = listTraffic.FindIndex(s => s.Area == item.Area && s.IP == objAGV.IP);                                               
                                                if (index != -1)
                                                { 
                                                    //释放被管制的AGV,不能寻找自己
                                                    List<TrafficInfo> listOutTraffic = listTraffic.FindAll(s => s.Area == item.Area && s.IP != objAGV.IP);
                                                    if (listOutTraffic.Count != 0)
                                                    {
                                                        //发送释放信号
                                                        Thread.Sleep(200); //延时200ms再发释放，以防AGV不释放
                                                        OrderList objOrderList = new OrderList() { CMD = 0x15 };
                                                        objAGVCommunicationManager.SendDataByIP(listOutTraffic[0].IP, this.objServerHelper.SocketDic, objOrderList);//发送数据 释放最前面一台
                                                        int outIndex = listTraffic.FindIndex(s => s.Area == item.Area && s.IP == listOutTraffic[0].IP);                                                      
                                                        lock (listTraffic)
                                                        {
                                                            if (outIndex != -1) listTraffic[outIndex].TrafficStatus = "通行中";
                                                        }
                                                    }
                                                    listTraffic.RemoveAt(index); //删除当前运行出交管区域的AGV信息   
                                                }
                                            }
                                        }//交管管理算法
                                    }//end 是否存在交管指令
                                } //end 地标判断
                            }//end 状态分析
                        }
                        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                        isFinishTrafficControl = false; //解锁可以处理其他信息
                        this.listTraffic.Sort(new AreaASC());
                        ShowTrafficView();//交管显示
                        Thread.Sleep(200);
                    }
                    catch (Exception ex)
                    {                        
                        MessageBox.Show(ex.Message);
                        Thread th = new Thread(TrafficThread);
                        th.IsBackground = true; //该线程为后台线程
                        th.Start(); //开始线程
                        isStartTraffic = true; //启动交管线程
                    }                   
                }                
            }
        }
        private void ShowTrafficView()
        {           
            lock(this.listTraffic)
            {
                while (isFinishTrafficControl) ;
                this.dgvTrafficView.Invoke(new Action<List<TrafficInfo>>(s =>
                {
                    this.dgvTrafficView.AutoGenerateColumns = false; this.dgvTrafficView.DataSource = null; this.dgvTrafficView.DataSource = s;
                }), listTraffic);
            }                                    
        }
        #endregion

        #region 客户端连接线程
        /// <summary>
        /// 创建一个线程
        /// </summary>
        /// <param name="isStart"></param>
        private void StartClientConnectThread(bool isStart)
        {
            //创建一个交管的现场
            //ParameterizedThreadStart pts = new ParameterizedThreadStart(TrafficThread);
            Thread th = new Thread(ClientConnectThread);
            th.IsBackground = true; //该线程为后台线程
            if (isStart) th.Start(); //开始线程
            else th.Abort();
            this.isConnectServer = true; //运行连接服务端线程开关打开
        }
        /// <summary>
        /// 客户端实时接收服务端数据线程的执行
        /// </summary>
        private void ClientConnectThread()
        {
            while (true)
            {
                if (this.isConnectServer)
                {
                    try
                    {
                        for (int i = 0; i < this.dgvAGV.Rows.Count; i++)
                        {
                            string ip = this.dgvAGV.Rows[i].Cells["IP"].Value.ToString(); //获取IP
                            AGVInfo objAGVInfo = listLastAGVInfo.Find(s => s.IP == ip);//寻找对应IP地址信息
                            SocketClientManager objSocketClientManager = new SocketClientManager();

                            if (!dicSocketClient.ContainsKey(ip))
                            {
                                SocketError socketError = objSocketClientManager.Connect(objAGVInfo.IP, objAGVInfo.Port);
                                
                                if (socketError == SocketError.Success)
                                {
                                    if (objSocketClientManager.Connected)
                                    {
                                        objSocketClientManager.OnReceiveData += RecMsg;  //关联客户端接收事件
                                        objSocketClientManager.OnServerClosed += ClientClose; //关联服务端断开事件
                                        this.dicSocketClient.Add(ip, objSocketClientManager);  //增加一个服务端连接的集合
                                        //上线列表显示
                                        this.LoginIPList.Add(objAGVInfo.IP);
                                        this.lbAGV.Invoke(new Action<List<string>>(s => { this.lbAGV.DataSource = null; this.lbAGV.DataSource = LoginIPList; }), LoginIPList);
                                        //AGV在线状态刷新
                                        UpdateAGVStatus(true, ip.ToString());
                                    }
                                }
                            }
                            else if (dicSocketClient.ContainsKey(ip)) //如果改IP已经存在列表，如果断开连接则立马清除连接列表中信息
                            {
                                if (!dicSocketClient[ip].Connected)
                                {
                                    this.dicSocketClient.Remove(ip);
                                    //上线列表显示
                                    this.LoginIPList.Remove(ip);
                                    this.lbAGV.Invoke(new Action<List<string>>(s => { this.lbAGV.DataSource = null; this.lbAGV.DataSource = LoginIPList; }), LoginIPList);
                                    //AGV在线状态刷新
                                    UpdateAGVStatus(false, ip.ToString());
                                }
                            }
                        }
                    }
                    catch (SocketException ex)
                    {
                        MessageBox.Show("服务端连接异常，异常信息："+ex.Message,"连接");
                    }
                    catch (Exception ex)
                    {

                        MessageBox.Show(ex.Message,"连接");
                    }
                                       
                }
                Thread.Sleep(5000);
            }
        }
     
        /// <summary>
        /// 服务端数据接收事件
        /// </summary>
        /// <param name="rec">接收数组</param>
        /// <param name="ip">服务端的IP</param>
        private void RecMsg(object rec,string ip)
        {
            try
            {
                byte[] buffer = (byte[])rec;
                AGVInfo objPreAGVInfo = listLastAGVInfo.Find(s => s.IP == ip); //根据IP寻找到当前AGV其他信息
                if (objPreAGVInfo != null)
                {
                    AGVInfo objAgvData = objAGVCommunicationManager.ResolutionProtocol(buffer, objPreAGVInfo); //AGV协议信息的解析
                    UpdateAGVStatus(objAgvData);
                }
            }
            catch (SocketException ex)
            {
                MessageBox.Show(ip + "数据接收异常!异常信息" + ex.Message, "接收");
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.Message,"服务器异常");
            }
                       
            //string str = new SerialPortHelper.AlgorithmHelper().BytesTo16(data, SerialPortHelper.Enum16Hex.Blank);
            //MessageBox.Show(str + ip);
        }
        /// <summary>
        /// 服务端断开事件
        /// </summary>
        /// <param name="ip"></param>
        private void ClientClose(string ip)
        {
            try
            {
                // MessageBox.Show(ip);
                UpdateAGVStatus(false, ip); //掉线显示
                this.LoginIPList.Remove(ip);
                this.lbAGV.Invoke(new Action<List<string>>(s => { this.lbAGV.DataSource = null; this.lbAGV.DataSource = LoginIPList; }), LoginIPList);               
                dicSocketClient.Remove(ip); //从集合中删除已掉线的AGV
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        /// <summary>
        /// 服务的断开
        /// </summary>
        private void ServerDisconnect()
        {
            if (this.dicSocketClient.Count != 0)
            {
                //逐一断开服务器的连接
                foreach (SocketClientManager item in this.dicSocketClient.Values)
                {
                    item.Disconnect();                  
                }
                foreach (string  item in this.dicSocketClient.Keys)
                {
                    UpdateAGVStatus(false, item); //掉线显示
                }
            }
            this.dicSocketClient.Clear();//清空服务器连接集合
        }
        #endregion

        #region 调度系统调度线程
        private void TaskScheduling()
        {
            try
            {
                while (true)
                {
                    if (isRun)
                    {
                        exCallLock = true;//显示上锁
                        //执行调度任务并返回完成的数据列表
                        // List<ExCall> objListExCall = objAGVCommunicationManager.TaskScheduling(this.dgvAGV, this.dgvStandbyCall, this.objServerHelper.SocketDic, listExCall);
                        List<ExCall> objListExCall = objAGVCommunicationManager.TaskScheduling(this.dgvAGV, this.dgvStandbyCall, this.objServerHelper.SocketDic, listExCall);
                        //更新已完成派车的列表
                        if (objListExCall.Count != 0)
                        {
                            this.listFinishCall.AddRange(objListExCall);
                            this.dgvFinishCall.Invoke(new Action<List<ExCall>>((s) =>
                            {
                                this.dgvFinishCall.AutoGenerateColumns = false;
                                this.dgvFinishCall.DataSource = null;
                                this.dgvFinishCall.DataSource = s;
                            }), this.listFinishCall);
                            //保存呼叫完成的信息到数据库
                            objRemoteIOManager.AddFinishCallByTran(objListExCall);
                        }
                        exCallLock = false;//解锁                                
                    }
                    Thread.Sleep(5000);
                }
            }
            catch (Exception ex)
            {
                
                MessageBox.Show(ex.Message);
            }
            
        }
        #endregion

        #region AGV状态刷新
        /// <summary>
        /// 刷新AGV在线状态
        /// </summary>
        /// <param name="status">true:上线 false:掉线</param>
        /// <param name="ip">IP地址</param>
        private void UpdateAGVStatus(bool status,string ip)
        {
            try
            {
                //this.dgvAGV.Invoke(new Action<string, bool>((s, a) =>
                //{
                    //查找登录的客户端IP地址，并显示当前在线状态
                    for (int i = 0; i < this.dgvAGV.Rows.Count; i++)
                    {
                        if (this.dgvAGV.Rows[i].Cells["IP"].Value.ToString() == ip)
                        {
                            if (status == true)
                            {
                                this.dgvAGV.Rows[i].Cells["OnLineStatus"].Value = "在线";
                                this.dgvAGV.Rows[i].Cells["UpdateTime"].Value = DateTime.Now;
                            }
                            else
                            {
                                this.dgvAGV.Rows[i].Cells["OnLineStatus"].Value = "离线";
                            }
                            break;
                        }
                    }
                //}), ip, status);
            }
            catch (Exception ex)
            {
                
                MessageBox.Show("状态更新异常！异常信息："+ex.Message);
            }
            
        }
        /// <summary>
        /// 更新AGV状态
        /// </summary>
        /// <param name="objAGV"></param>
        private void UpdateAGVStatus(AGVInfo objAGV)
        {
            this.dgvAGV.Invoke(new Action<AGVInfo>(s => 
            {
                for (int i = 0; i < this.dgvAGV.Rows.Count; i++)
                {
                    if (this.dgvAGV.Rows[i].Cells["IP"].Value.ToString() == s.IP)
                    {
                        this.dgvAGV.Rows[i].Cells["IP"].Value = s.IP;
                        this.dgvAGV.Rows[i].Cells["OnLineStatus"].Value = s.OnLineStatus;
                        this.dgvAGV.Rows[i].Cells["PreAGVStatus"].Value = s.PreAGVStatus;
                        this.dgvAGV.Rows[i].Cells["AimStation"].Value = s.AimStation;
                        this.dgvAGV.Rows[i].Cells["PreLandNum"].Value = s.PreLandNum;
                        this.dgvAGV.Rows[i].Cells["LiftStatus"].Value = s.LiftStatus;
                        this.dgvAGV.Rows[i].Cells["Speed"].Value = s.Speed;
                        this.dgvAGV.Rows[i].Cells["Electricity"].Value = s.Electricity;
                        this.dgvAGV.Rows[i].Cells["UpdateTime"].Value = s.UpdateTime;
                        this.dgvAGV.Rows[i].Cells["AGVName"].Value = s.AGVName;
                        this.dgvAGV.Rows[i].Cells["TrackName"].Value = s.TrackName;
                        break;
                    }
                }
            }), objAGV);
        }
        #endregion

        #region 系统退出
        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            DialogResult result = MessageBox.Show("确认退出系统？", "退出提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
            if (result == DialogResult.Cancel)
            {
                e.Cancel = true;
            }
            else
            {
                new BLL.SysAdminManager().WriteLogOutInfo(Program.currentAdmins.LoginId.ToString()); //退出记录编写
            }
        }

        private void 退出系统QToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        #endregion

        #region 定时器工作
        private void timAGVStaus_Tick(object sender, EventArgs e)
        {
            this.lblSysTime.Text = sysRunTime.Elapsed.Days + "天" + sysRunTime.Elapsed.Hours + "小时" + sysRunTime.Elapsed.Minutes + "分" + sysRunTime.Elapsed.Seconds + "秒";
           
            //ShowTrafficView();//交管显示
            for (int i = 0; i < this.dgvAGV.Rows.Count; i++)
            {
                DateTime dt = Convert.ToDateTime(this.dgvAGV.Rows[i].Cells["UpdateTime"].Value); //获取上次更新时间
                DateTime dtNow = DateTime.Now;
                if ((dtNow - dt).Seconds > 5)
                {
                    //this.dgvAGV.Invoke(new Action<int>((s) => { this.dgvAGV.Rows[s].Cells["PreAGVStatus"].Value = "失联"; }), i);
                    this.dgvAGV.Rows[i].Cells["PreAGVStatus"].Value = "失联";
                    string ip = this.dgvAGV.Rows[i].Cells["IP"].Value.ToString(); //获取IP                 
                    //当AGV超时没有上传状态时则重新发送上传状态
                    foreach (AsyncUserToken item in this.m_socket.ClientList)
                    {
                        if (item.Socket.Connected && item.IPAddress.ToString() == ip)
                        {
                            try
                            {
                                OrderList objOrderList = new OrderList() { CMD = 22, Data = 1 };
                                bool sendStatus = objAGVCommunicationManager.SendDataByIP(item.IPAddress.ToString(), this.objServerHelper.SocketDic, objOrderList);//发送数据 启动自动上报信息
                                if ((dtNow - dt).Seconds > 15)
                                {
                                    m_socket.CloseClient(item);
                                    this.LoginIPList.Remove(item.IPAddress.ToString()); //清除显示
                                    LoginListShow();
                                    break;
                                }
                            }
                            catch (Exception ex)
                            {
                                m_socket.CloseClient(item);
                                this.LoginIPList.Remove(item.IPAddress.ToString()); //清除显示
                                LoginListShow();
                                break;
                                //MessageBox.Show("定时器刷新失败！异常信息：" + ex.Message);
                            }                                                     
                        }
                    }                            
                }
            }                           
          }
         #endregion

        #region 窗体打开
        public static FrmAGVEdit objFrmAGVEdit = null;
        private void 添加AGVToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (objFrmAGVEdit == null)
            {
                objFrmAGVEdit = new FrmAGVEdit();
                //委托办法关联
                objFrmAGVEdit.showAGVInfo += ShowAGVInfo;//委托办法的关联
                objFrmAGVEdit.Show();
            }
            else
            {
                objFrmAGVEdit.Activate();//激活只能在最小化的时候起作用
                objFrmAGVEdit.WindowState = FormWindowState.Normal; 
            }
        }
        public static FrmManualControl objFrmManualControl = null;
        private void 手动控制CToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (objFrmManualControl == null)
            {
                objFrmManualControl = new FrmManualControl();
                objFrmManualControl.objServerSend += SendData;//委托办法的关联
                objFrmManualControl.Show();
            }
            else
            {
                objFrmManualControl.Activate();//激活只能在最小化的时候起作用
                objFrmManualControl.WindowState = FormWindowState.Normal;
            }
        }
        public static FrmManualCall objFrmManualCall = null;
        private void 手动添加任务ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (objFrmManualCall == null)
            {
                objFrmManualCall = new FrmManualCall();
                objFrmManualCall.ImportCallInfo += LoadCallInfo;//委托办法的关联
                objFrmManualCall.Show();
            }
            else
            {
                objFrmManualCall.Activate();//激活只能在最小化的时候起作用
                objFrmManualCall.WindowState = FormWindowState.Normal;
            }
        }

        public static FrmEditRemoteIO objFrmEditRemoteIO = null;
        private void 呼叫编辑CToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (objFrmEditRemoteIO == null)
            {
                objFrmEditRemoteIO = new FrmEditRemoteIO();
                objFrmEditRemoteIO.ipTypeOutput += ShowTypeIP;//委托办法的关联
                objFrmEditRemoteIO.Show();
            }
            else
            {
                objFrmEditRemoteIO.Activate();//激活只能在最小化的时候起作用
                objFrmEditRemoteIO.WindowState = FormWindowState.Normal;
            }
        }
        public static FrmTrafficEdit objFrmTrafficEdit = null;
        private void 交通管制编辑TToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (objFrmTrafficEdit == null)
            {
                objFrmTrafficEdit = new FrmTrafficEdit();
                //objFrmEditRemoteIO.ipTypeOutput += ShowTypeIP;//委托办法的关联
                objFrmTrafficEdit.Show();
            }
            else
            {
                objFrmTrafficEdit.Activate();//激活只能在最小化的时候起作用
                objFrmTrafficEdit.WindowState = FormWindowState.Normal;
            }
        }
        public static FrmTrafficView objFrmTrafficView = null;
        private void 交管显示VToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (objFrmTrafficView == null)
            {
                objFrmTrafficView = new FrmTrafficView();
                //this.TrafficInfoShow += objFrmTrafficView.Receiver; ;//委托办法的关联
                this.TrafficInfoShow +=new TrafficView(objFrmTrafficView.Receiver); ;//委托办法的关联
                objFrmTrafficView.Show();
            }
            else
            {
                objFrmTrafficView.Activate();//激活只能在最小化的时候起作用
                objFrmTrafficView.WindowState = FormWindowState.Normal;
            }
        }
        public static FrmWatchBoard objFrmWatchBoard = null;
        private void 看板系统显示ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (objFrmWatchBoard == null)
            {
                objFrmWatchBoard = new FrmWatchBoard();
                this.WatchBoarShow += objFrmWatchBoard.Receiver; ;//委托办法的关联
                objFrmWatchBoard.Show();
                this.timWatchBoard.Start(); //开启时钟
            }
            else
            {
                objFrmWatchBoard.Activate();//激活只能在最小化的时候起作用
                objFrmWatchBoard.WindowState = FormWindowState.Normal;
            }
        }
        public static FrmQuery objFrmQuery = null;
        private void 完成数据查询FToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (objFrmQuery == null)
            {
                objFrmQuery = new FrmQuery();
                objFrmQuery.Show();

            }
            else
            {
                objFrmQuery.Activate();//激活只能在最小化的时候起作用
                objFrmQuery.WindowState = FormWindowState.Normal;
            }
        }
        public static FrmLogQuery objFrmLogQuery = null;
        private void 登录日志LToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (objFrmLogQuery == null)
            {
                objFrmLogQuery = new FrmLogQuery();
                objFrmLogQuery.Show();

            }
            else
            {
                objFrmLogQuery.Activate();//激活只能在最小化的时候起作用
                objFrmLogQuery.WindowState = FormWindowState.Normal;
            }
        }
        public static FrmMapEdit objFrmMapEdit = null;
        private void 新增地图AToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (objFrmMapEdit == null)
            {
                objFrmMapEdit = new FrmMapEdit();
                objFrmMapEdit.Show();

            }
            else
            {
                objFrmMapEdit.Activate();//激活只能在最小化的时候起作用
                objFrmMapEdit.WindowState = FormWindowState.Normal;
            }
        }
        #endregion

        #region 呼叫显示、取消、完成显示
        //呼叫取消
               
        private void dgvStandbyCall_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
        {
            Common.DataGridViewStyle.DgvRowPostPaint(this.dgvStandbyCall,e);
        }

        private void dgvFinishCall_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
        {
            Common.DataGridViewStyle.DgvRowPostPaint(this.dgvFinishCall,e);
        }
        private void dgvStandbyCall_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                if (this.dgvStandbyCall.CurrentRow != null && this.dgvStandbyCall.Rows.Count != 0)
                {
                    DataGridViewColumn column = dgvStandbyCall.Columns[e.ColumnIndex];
                    if (column is DataGridViewButtonColumn)
                    {
                        //删除数据里面对应的数据
                        objRemoteIOManager.DeleteUnfinishCall(this.listExCall[e.RowIndex]);
                        this.listExCall.RemoveAt(e.RowIndex); //删除数据
                        this.dgvStandbyCall.DataSource = null;
                        this.dgvStandbyCall.DataSource = listExCall;
                    }
                }
            }
            catch (Exception ex)
            {

                MessageBox.Show("删除失败，详细信息：" + ex.Message);
            }
            
        }
        private void FinishCallShow()
        {
            this.dgvFinishCall.Invoke(new Action<List<ExCall>>((s) =>
            {
                this.dgvFinishCall.AutoGenerateColumns = false;
                this.dgvFinishCall.DataSource = null;
                this.dgvFinishCall.DataSource = s;
            }), this.listFinishCall);  
        }

        private void 删除DToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (this.dgvFinishCall.CurrentRow != null && this.dgvFinishCall.RowCount != 0)
            {
                this.listFinishCall.RemoveAt(this.dgvFinishCall.CurrentRow.Index);
                FinishCallShow();
            }
            
        }
        private void 清空QToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.listFinishCall.Clear();
            FinishCallShow();
        }
        #endregion   

        #region 看板系统
        private void timWatchBoard_Tick(object sender, EventArgs e)
        {
            if (objFrmWatchBoard != null)
            {
                int AGVCount = this.dgvAGV.Rows.Count;//AGV数量
                int onLineCount = 0; //上线AGV数量
                int outLintCount = 0;//下线AGV数量
                int remoteIOCount = 0;//IO上线数量
                foreach (DataGridViewRow item in dgvAGV.Rows)
                {
                    if(item.Cells["OnLineStatus"].Value!=null)
                    if (item.Cells["OnLineStatus"].Value.ToString() == "在线")
                    {
                        onLineCount++;
                    }
                }
                if (AGVCount != 0)
                    outLintCount = AGVCount - onLineCount;
                if(this.lbAGV.Items.Count !=0)
                {
                    remoteIOCount = this.lbAGV.Items.Count - onLineCount;
                }
                
                WatchBoards objWatchBoards = new WatchBoards()
                {
                    AGVOnlineCount = onLineCount,
                    AGVOutCount = outLintCount,
                    RemoteIOCount = remoteIOCount
                };
                WatchBoarShow.Invoke(objWatchBoards);
            }
            else
            {
                this.timWatchBoard.Stop();
            }
        }
        #endregion

        #region 报警显示
        private void timAlarm_Tick(object sender, EventArgs e)
        {
            bool isExistsAlarm = false; //是否存在异常
            //获取报警状态
            foreach (DataGridViewRow item in this.dgvAGV.Rows)
            {
                if (objAGVCommunicationManager.GetAlarmFlag(item.Cells["PreAGVStatus"].Value.ToString(), item.Cells["OnLineStatus"].Value.ToString()))
                {
                    isExistsAlarm = true;
                    break;
                }
            }
            //根据AGV当前状态改变显示颜色
            foreach (DataGridViewRow row in this.dgvAGV.Rows)
            {
                if (row.Cells["PreAGVStatus"].Value.ToString() == "失联" || row.Cells["OnLineStatus"].Value.ToString() == "失联")
                {
                    row.Cells["PreAGVStatus"].Style.BackColor = Color.Red;
                    row.Cells["OnLineStatus"].Style.BackColor = Color.Red;
                }
                else
                {
                    row.Cells["PreAGVStatus"].Style.BackColor = Color.White;
                    row.Cells["OnLineStatus"].Style.BackColor = Color.White;
                }
            }
            try
            {
                if (isExistsAlarm && alarmSend == false)
                {                    
                    if (objAGVCommunicationManager.SendRemoteIOByIP(m_socket, alarmIP, true))
                    {
                        alarmSend = true;
                        alarmClear = false;
                    }
                }
                else if (isExistsAlarm == false && alarmClear == false)
                {              
                    if (objAGVCommunicationManager.SendRemoteIOByIP(m_socket, alarmIP, false)) 
                    {
                        alarmSend = false;
                        alarmClear = true;
                    }
                }
            }
            catch (Exception ex) 
            {

                MessageBox.Show("报警信息发送失败！异常详细信息："+ex.Message);
            }

        }
        #endregion

        

    }
    //交管区域升序排列
    class AreaASC : IComparer<TrafficInfo>
    {
        public int Compare(TrafficInfo x, TrafficInfo y)
        {
            return x.Area - y.Area;
        }
    }
}
